iT邦幫忙

2024 iThome 鐵人賽

DAY 9
0
Software Development

Java工程師的報表入門與實作系列 第 9

JasperReports-使用Group功能將報表資料分組

  • 分享至 

  • xImage
  •  

除了元素、屬性、參數之外,JasperReports還有個不容易發現的功能:Group

Group

Group是用來根據特定欄位或表達式對資料進行分組的功能。透過分組,報表資料可以根據該欄位(如部門、課程、客戶等)進行邏輯上的劃分,並能夠在每個組別的開頭或結尾處插入特定內容,如小計、摘要或群組標題。

如何使用Group

我想繼續對學生基本資料報表以年級分組,希望報表不同組別的開始都從新的一頁顯示資料。

先為資料排序

JasperReports的Group是依據特定的欄位或表達式來進行的,因此相同的值的資料應該連續出現在報表中,否則JasperReports會在遇到不同值的時候將資料視為新的一組,若沒有排序就會變成很多組別但區分的邏輯混亂。

  • 我想用 「年級」(grade) 這個欄位分組,所以我先修改Dao中SQL的排序,以年級由小到大、studentId由小到大進行排序
@Override
public List<StudentAndDepartmentDto> getStudentAndDepartmentData() {
    QStudentEntity qStudent = QStudentEntity.studentEntity;
    QDepartmentEntity qDepartment = QDepartmentEntity.departmentEntity;

    return queryFactory.select(Projections.bean(
                StudentAndDepartmentDto.class,
                qStudent.studentId, qStudent.firstName, qStudent.lastName, 
                qStudent.gender, qStudent.grade,
                qDepartment.departmentId, qDepartment.departmentName, 
                qDepartment.departmentDesc))
            .from(qStudent)
            .innerJoin(qDepartment)
            .on(qStudent.departmentId.eq(qDepartment.departmentId))
            // 以年級由小到大、studentId由小到大進行排序
            .orderBy(qStudent.grade.asc(), qStudent.studentId.asc())
            .fetch();
}

新增Group

  • Group沒有圖示和元素,要新增Group是在左下區域,在報表點選右鍵 -> 「Create Group」
  • 這時候會出現設定視窗,可以為Group命名,我將Group命名為「GroupByGrade」,並點選作為分組依據的Field

Group Header、Group Footer

  • 新增Group之後,模板上會自動出現Group Header、Group Footer這兩個Band,這可以設定每個組別要顯示的頁首、頁尾
  • Group Header只會在每個組別的第一頁出現,如果沒放置任何元素的話,實際匯出的報表欄位(Column Header)與資料內容(Detail)之間會空一行,因此如果沒什麼特別的資訊要放,建議把Column Header的欄位Static Text都移到Group Header,刪掉原本的Column Header
  • 同理Group Footer只會在每個組別的最後一頁出現,因此我把Summary刪掉,P${studentNum}參數移到Group Footer中
    https://ithelp.ithome.com.tw/upload/images/20240923/20169094sRrTYSVqNA.jpg

使用變數(Variable)顯示各組別的資訊

原先的參數P${studentNum}是後端程式計算的學生總人數,但是現在Group Footer是顯示各組別的資料,根據情境顯示各組別的學生人數更適合。
要顯示各組別的學生人數,當然也可以新增變數,同樣用後端計算每個年級的人數,再以REPORT_PARAMETERS_MAP傳遞到報表,只是現在有個更簡單的方法,就是使用JasperReports的變數。
變數與程式語言中的變數功能很像,是用來儲存和計算報表資料的工具,我將會於下一篇對變數有深入的介紹。

  • 我們先對Group Footer的Text Field點兩下 -> 刪除原先的P${studentNum} -> 在左側點選「Variable」,在中間的區塊就發現JasperReports非常貼心,自動幫你產生一個「GroupByGrade_COUNT」的變數,Count這個類型顧名思義就是計算數量的,這個變數是在新增Group之後JasperReports預設會產生用來計算每個組別的資料數量的,而我們一個資料就是一個學生,正好可以使用這個變數$V{GroupByGrade_COUNT}
  • 經過剛剛的設定,我們的分組模板已經完成了

設定各組別資料於新的一頁開始

由於資料很多,如果資料都放在一起會導致每個Group很不容易區別,因此我想設定各組別資料都於新的一頁開始。

  • (1.)到左下區域點選Group Header -> (2.)到右下設定屬性的區域,將「Start New Page」打勾,就完成啦

匯出PDF

  • 匯出pdf後,可以看到第一個Group都是一年級學生的資料
  • 組別最後會顯示變數計算的該組學生數量,下一個組別也會從新的一頁開始

Reference


上一篇
JasperReports-為PDF加上浮水印
下一篇
JasperReports-為報表加上頁碼
系列文
Java工程師的報表入門與實作15
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言